﻿using Extented.UI.Core.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Extented.UI.Core.Native
{
    public abstract class RenderControlBaseContext : FrameworkRenderElementContext
    {
        HorizontalAlignment hca;
        VerticalAlignment vca;
        public HorizontalAlignment HorizontalContentAlignment
        {
            get { return hca; }
            set { SetProperty(ref hca, value, FREInvalidateOptions.UpdateLayout, HorizontalContentAlignmentChanged); }
        }
        public VerticalAlignment VerticalContentAlignment
        {
            get { return vca; }
            set { SetProperty(ref vca, value, FREInvalidateOptions.UpdateLayout, VerticalContentAlignmentChanged); }
        }
        public override bool AttachToRoot { get { return Visibility != null ? Visibility.Value == System.Windows.Visibility.Visible : Factory.Visibility == System.Windows.Visibility.Visible; } }
        public virtual FrameworkElement Control { get; internal set; }
        public Transform GeneralTransform { get; protected set; }
        protected RenderControlBaseContext(RenderControlBase factory)
            : base(factory)
        {
        }
        protected bool CanSetValue(string propertyName)
        {
            return IsContextProperty(propertyName) || Control != null;
        }
        protected virtual bool IsContextProperty(string propertyName) { return string.Equals("Opacity", propertyName); }
        protected override void SetValueOverride(string propertyName, object value)
        {
            if (!CanSetValue(propertyName))
                return;
            if (object.Equals(GetValue(propertyName), value))
                return;
            if (IsContextProperty(propertyName))
                base.SetValueOverride(propertyName, value);
            else
                RenderTriggerHelper.SetConvertedValue(Control, propertyName, value);
        }
        protected override void ResetValueOverride(string propertyName)
        {
            if (!CanSetValue(propertyName))
                return;
            if (IsContextProperty(propertyName))
                base.ResetValueOverride(propertyName);
            else
                RenderTriggerHelper.SetConvertedValue(Control, propertyName, null);
        }
        protected override object GetValueOverride(string propertyName)
        {
            if (!CanSetValue(propertyName))
                return null;
            if (IsContextProperty(propertyName))
                return base.GetValueOverride(propertyName);
            else
                return RenderTriggerHelper.GetValue(Control, propertyName);
        }
        protected override void UpdateOpacity()
        {
            Control.Opacity = ActualOpacity * RenderTreeHelper.RenderAncestors(this).Select(x => x.ActualOpacity).Aggregate((a, b) => a * b);
        }
        Matrix currentMatrixTransform = Matrix.Identity;
        public override bool ShouldUseTransform()
        {
            base.ShouldUseTransform();
            return true;
        }
        public override void UpdateRenderTransform()
        {
            base.UpdateRenderTransform();
            UpdateGeneralTransform();
        }
        protected virtual void UpdateGeneralTransform()
        {
            double x = VisualOffset.X, y = VisualOffset.Y;
            foreach (var anc in RenderTreeHelper.RenderAncestors(this))
            {
                x += anc.VisualOffset.X;
                y += anc.VisualOffset.Y;
            }
            var translateTransform = Matrix.Identity;
            translateTransform.Translate(x, y);
            if (currentMatrixTransform.Equals(translateTransform))
                return;
            var mt = new MatrixTransform(translateTransform);
            mt.Freeze();
            GeneralTransform = mt;
        }
        protected virtual void HorizontalContentAlignmentChanged()
        {
            var control = Control as Control;
            if (control != null)
                control.HorizontalContentAlignment = HorizontalContentAlignment;
        }
        protected virtual void VerticalContentAlignmentChanged()
        {
            var control = Control as Control;
            if (control != null)
                control.VerticalContentAlignment = VerticalContentAlignment;
        }
        protected override void OnForegroundChanged(object oldValue, object newValue)
        {
            base.OnForegroundChanged(oldValue, newValue);
            UpdateControlForeground();
        }
        protected internal virtual void UpdateControlForeground()
        {
            if (Control != null)
                Control.SetCurrentValue(System.Windows.Documents.TextElement.ForegroundProperty, Foreground);
        }
    }
}
